#include "rads_base.hpp"
#include <ros/ros.h>
#include "rads/rads_camera.h"  // 保留您的头文件包含方式
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/tcp.h>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#define TCP_PORT 8500


typedef unsigned char UINT8T;
typedef unsigned short UINT16T;
typedef unsigned int UINT32T;
// 定义一个结构体类型，避免在函数中使用匿名结构体
typedef struct {
    ros::Publisher pub;
} AcceptThreadData;

// 定义HTTP_SERVICE函数使用的线程数据结构体
typedef struct {
    int sfd;
    ros::Publisher pub;
} HttpThreadData;
struct http_parser_urt
{
    char api[32];
    char method; /* 0:GET;1:POST */
};
// 解析报警信息的函数
void parse_alarm_info(const char* json_str, rads::rads_camera& msg) {

    rapidjson::Document document;
    //ROS_INFO("Received JSON: %s", json_str); // 新增日志
    // 解析JSON字符串
    if (document.Parse(json_str).HasParseError()) {
        ROS_ERROR("Failed to parse JSON data");
        return;
    }
    
    // 检查根对象是否存在
    if (!document.IsObject()) {
        ROS_ERROR("JSON data is not an object");
        return;
    }
    
    // 解析基本字段
    if (document.HasMember("devIp") && document["devIp"].IsString()) {
        msg.devIp = document["devIp"].GetString();
    }
    
    if (document.HasMember("Alarmtype") && document["Alarmtype"].IsInt()) {
        msg.Alarmtype = document["Alarmtype"].GetInt();
    }
    
    if (document.HasMember("preset") && document["preset"].IsInt()) {
        msg.preset = document["preset"].GetInt();
    }
    
    if (document.HasMember("preAlarmSum") && document["preAlarmSum"].IsInt()) {
        msg.preAlarmSum = document["preAlarmSum"].GetInt();
    }
    
    if (document.HasMember("alarmSum") && document["alarmSum"].IsInt()) {
        msg.alarmSum = document["alarmSum"].GetInt();
    }
    
 // 将mtAlarmInfo数组转换为字符串
    std::stringstream ss;
    const rapidjson::Value& mtAlarmArray = document["mtAlarmInfo"];
    if (mtAlarmArray.Size() > 0) {
        const rapidjson::Value& alarm = mtAlarmArray[0];
        
        ss << "[{"
           << "\"mtAlarmid\":" << alarm["mtAlarmid"].GetInt() << ","
           << "\"mtAlarmlevel\":" << alarm["mtAlarmlevel"].GetInt() << ","
           << "\"mtAlarmType\":" << alarm["mtAlarmType"].GetInt() << ","
           << "\"maxtemp\":" << std::fixed << std::setprecision(6) << alarm["maxtemp"].GetFloat() << ","
           << "\"mintemp\":" << std::fixed << std::setprecision(6) << alarm["mintemp"].GetFloat() << ","
           << "\"avgtemp\":" << std::fixed << std::setprecision(6) << alarm["avgtemp"].GetFloat() << ","
           << "\"maxPointX\":" << alarm["maxPointX"].GetInt() << ","
           << "\"maxPointY\":" << alarm["maxPointY"].GetInt() << ","
           << "\"minPointX\":" << alarm["minPointX"].GetInt() << ","
           << "\"minPointY\":" << alarm["minPointY"].GetInt()
           << "}]";
    }
    
    msg.mtAlarmInfo = ss.str();
}
char parse_url(struct http_parser_urt * httpurl, char * strurl)
{
    char ret = 0;
    char * line_start = NULL;
    char * line_end = NULL;
    char * start_temp = NULL;
    char * end_temp = NULL;
    char * line_temp = NULL;

    /* input check */
    if( (httpurl == NULL)||(strurl == NULL) )
    {
        ret = 1;
        return ret;
    }

    /* check http end flag */
    line_temp = (char *)strstr(strurl, "\r\n\r\n");
    if (line_temp == NULL)
    {
        ret = 1;
        return ret;
    }

    /* ----------------------------------- first line ------------------------------*/
    /* Determine the first and end addresses of a line */
    line_start = strurl;
    line_end = (char *)strstr(line_start, "\r\n");
    if (line_end == NULL)
    {
        ret = 1;
        return ret;
    }

    /* find method name */
    if (strncmp(line_start, "GET ", 4) == 0)
    {
        httpurl->method = 0;
        start_temp = line_start + 4;
    }
    else if (strncmp(strurl, "POST ", 5) == 0)
    {
        httpurl->method = 1;
        start_temp = line_start + 5;
    }
    else
    {
        /* now do not suport method */
        ret = 1;
        return ret;
    }

    /* find api name */
    start_temp++;
    end_temp = (char *)strstr(line_start, " HTTP");
    strncpy(httpurl->api, start_temp, end_temp-start_temp);

    return ret;
}

void http_get_alarm(int sfd, struct sockaddr_in saddr, ros::Publisher& pub)
{
    char respBuf[1024] = {0};
    int respXmlLen = 0, respBufLen = 0;
    char respXml[1024] = {0};
    int sendlen, recvlen;
    char *line_start = NULL;
    char *line_end = NULL;

    int port = ntohs(saddr.sin_port);
    char server_ip[32] = {0};
    char *temp_ip = inet_ntoa(saddr.sin_addr);
    memcpy(server_ip, temp_ip, strlen(temp_ip));

    respXmlLen = sprintf(respXml + respXmlLen, "{\r\n");
    respXmlLen += sprintf(respXml + respXmlLen, "\"hostIp\": \"%s\",\r\n", LOCAL_IP);  // 使用宏定义的本机IP
    respXmlLen += sprintf(respXml + respXmlLen, "\"hostPort\": %d\r\n", 8888);
    respXmlLen += sprintf(respXml + respXmlLen, "}\r\n");

    respBufLen = sprintf(respBuf + respBufLen, "POST %s HTTP/1.1\r\n", "/api/v1/alarm/push");
    respBufLen += sprintf(respBuf + respBufLen, "Content-Type: application/json\r\n");
    respBufLen += sprintf(respBuf + respBufLen, "User-Agent: test\r\n");
    respBufLen += sprintf(respBuf + respBufLen, "Accept: */*\r\n");
    respBufLen += sprintf(respBuf + respBufLen, "Token: 11:11:11:11:11:11\r\n");
    respBufLen += sprintf(respBuf + respBufLen, "Host: %s:%d\r\n", server_ip, port);
    respBufLen += sprintf(respBuf + respBufLen, "Accept-Encoding: gzip, deflate, br\r\n");
    respBufLen += sprintf(respBuf + respBufLen, "Content-Length: %d\r\n\r\n", respXmlLen);
    respBufLen += sprintf(respBuf + respBufLen, "%s\r\n", respXml);

    sendlen = send(sfd, respBuf, respBufLen, 0); // 发送请求
    if(sendlen < 0)
    {
        perror("send error");
        return ;
    }

    memset(respXml, 0, sizeof(respXml));
    recvlen = recv(sfd, respXml, sizeof(respXml), 0); //接收回应
    //ROS_INFO("recvlen = %d", recvlen);
    if(recvlen < 0)
    {
        perror("recv error");
        return ;
    }
    //ROS_INFO("respXml = %s", respXml);
    //rads::rads_camera alarm_msg;
   // 调用解析函数
    //parse_alarm_info(respXml, alarm_msg);
    
    // 发布消息
    //pub.publish(alarm_msg);

    //ROS_INFO("Published alarm message: devIp=%s, Alarmtype=%d", 
    //        alarm_msg.devIp.c_str(), alarm_msg.Alarmtype);

    return ;
}

void http_post_alarm(char *recvbuff, int sfd, ros::Publisher& pub)
{
    char respBuf[1024] = {0};
    int sendlen;
    char val_str[5] = {0};
    char *line_start = NULL;
    char *line_end = NULL;
    int content_length;
    
    // 对数据进行分析处理
    line_start = (char *)strstr(recvbuff, "Content-Length: ");
    if (line_start != NULL)
    {
        line_end = (char *)strstr(line_start, "\r\n");
        if (line_end != NULL)
        {
            memcpy(val_str, line_start + strlen("Content-Length: "), 
                  line_end - line_start - strlen("Content-Length: "));
            content_length = atoi(val_str);
            //ROS_INFO("Content-Length: %d", content_length);
            
            if(content_length == 0)
            {
                //ROS_INFO("No alarm info received");
                goto send_response;
            }
            
            // 查找 HTTP 头部和正文的分隔符
            char *body_start = (char *)strstr(recvbuff, "\r\n\r\n");
            if (body_start == NULL) {
                body_start = (char *)strstr(recvbuff, "\n\n"); // 兼容非标准格式
                if (body_start == NULL) {
                    ROS_ERROR("Invalid HTTP request format: missing header/body separator");
                    goto send_response;
                }
                ROS_WARN("Using non-standard header/body separator: \\n\\n");
            }
            
            // 提取 JSON 数据（跳过分隔符）
            char *json_start = body_start + 4; // 跳过 "\r\n\r\n"
            int actual_data_len = strlen(json_start);
            
            //ROS_INFO("Extracted data length: %d", actual_data_len);
            //ROS_INFO("Content-Length vs Actual: %d vs %d", content_length, actual_data_len);
            
            // 计算 JSON 结束位置（根据 Content-Length）
            char *json_end = json_start + content_length;
            if (json_end > recvbuff + strlen(recvbuff)) {
                ROS_ERROR("Invalid Content-Length: exceeds buffer size");
                goto send_response;
            }
            
            // 提取严格按照 Content-Length 定义的 JSON 数据
            char json_data[8192] = {0};
            strncpy(json_data, json_start, content_length);
            json_data[content_length] = '\0'; // 确保字符串结束
            
            // 验证 JSON 完整性（检查是否以 '}' 结尾，且之前没有 '}'）
            bool json_complete = false;
            for (int i = content_length - 1; i >= 0; i--) {
                if (json_data[i] == '}') {
                    json_complete = true;
                    break;
                } else if (!isspace(json_data[i])) {
                    // 遇到非空格字符但不是 '}'，说明 JSON 不完整
                    break;
                }
            }
            
            if (!json_complete) {
                ROS_WARN("JSON may be incomplete: missing closing brace '}'");
                
                // 尝试修复不完整的 JSON（添加 '}'）
                char fixed_json[8192] = {0};
                snprintf(fixed_json, sizeof(fixed_json), "%s}", json_data);
                
                //ROS_INFO("Fixed JSON: %s", fixed_json);
                
                // 解析修复后的 JSON
                rads::rads_camera alarm_msg;
                parse_alarm_info(fixed_json, alarm_msg);
                pub.publish(alarm_msg);
                
                //ROS_INFO("Published alarm message with fixed JSON: devIp=%s, Alarmtype=%d", 
                //        alarm_msg.devIp.c_str(), alarm_msg.Alarmtype);
            } else {
                // 正常解析完整的 JSON
                //ROS_INFO("JSON is complete, parsing original data");
                //ROS_INFO("Original JSON: %s", json_data);
                
                rads::rads_camera alarm_msg;
                parse_alarm_info(json_data, alarm_msg);
                pub.publish(alarm_msg);
                
                //ROS_INFO("Published alarm message with complete JSON: devIp=%s, Alarmtype=%d", 
                //        alarm_msg.devIp.c_str(), alarm_msg.Alarmtype);
            }
        }
    }
    else {
        ROS_ERROR("HTTP request missing Content-Length header");
    }
    
send_response:
    // 给予设备回应
    memset(respBuf, 0, sizeof(respBuf));
    int respBufLen = sprintf(respBuf, "HTTP/1.1 %d %s\r\n", 200, "OK");
    respBufLen += sprintf(respBuf + respBufLen, "Content-Length: %d\r\n\r\n", 0);
    sendlen = send(sfd, respBuf, strlen(respBuf), 0);
    //ROS_INFO("Response sent, size: %d", sendlen);
}





void *HTTP_SERVICE(void *arg)
{
    // 使用预定义的结构体类型
    HttpThreadData *data = (HttpThreadData *)arg;
    int sfd = data->sfd;
    ros::Publisher pub = data->pub;

    char respBuf[1024] = {0};
    int recvlen, sendlen;
    struct timeval select_timeout;
    fd_set rset;
    int retVal = 0;
    char firstChar = '0';
    int respXmlLen = 0, respBufLen = 0;
    char respXml[1024] = {0};
    struct http_parser_urt url_val = {0};
    unsigned char recvbuff[8192];
    struct timeval timeout = {5, 0};
    fd_set fdset;

    int ret, cmdLength;

    while(ros::ok())
    {
        firstChar = '0';
        memset(recvbuff, 0, 8192);
        select_timeout.tv_sec = 20;
        select_timeout.tv_usec = 0;

        FD_ZERO(&rset);
        FD_SET(sfd, &rset);
        if(select(sfd+1, &rset, NULL, NULL, &select_timeout) > 0)
        {
            if(FD_ISSET(sfd, &rset))
            {
                if((recvlen=recv(sfd, &firstChar, 1, 0)) != 1)
                {
                    perror("recv head error\n");
                    break ;
                }
                if ((firstChar == 'P') || (firstChar == 'G'))
                {
                    recvbuff[0] = firstChar;
                    recvlen = recv(sfd, recvbuff + 1, 8192-1, 0);
                    if(recvlen < 0)
                    {
                        perror("recv data error\n");
                        break;
                    }
                }
                else
                {
                    continue;
                }

                if(recvlen > 12)
                {
                    // 修复：使用%zu格式化size_t类型的strlen返回值
                    //ROS_INFO("recvbuf len = %zu", strlen((char*)recvbuff));  // 类型转换
                    //ROS_INFO("recvbuf = %s", (char*)recvbuff);  // 类型转换
                    //ROS_INFO("-------------------33333---------------");

                    memset((char *)&url_val, 0x00, sizeof(struct http_parser_urt));
                    retVal = parse_url(&url_val, (char*)recvbuff);  // 显式类型转换

                    //ROS_INFO("url_val.method = %d", url_val.method);
                    if (url_val.method == 0)    //get
                    {
                        //各种case进行处理
                    }
                    else if (url_val.method == 1)    //post
                    {
                        //各种case进行处理
                        if (memcmp(url_val.api, "api/v1/alarm/Info", strlen(url_val.api)) == 0) // 主机端收到设备的POST请求，其中包含设备端传来的报警信息
                        {
                            //ROS_INFO("start http_post_alarm");
                            http_post_alarm((char*)recvbuff, sfd, pub);  // 显式类型转换
                        }
                        else
                        {
                            //ROS_INFO("----403--param-----%d--%s--", url_val.method, url_val.api);
                            respBufLen = sprintf(respBuf + respBufLen, "HTTP/1.1 %d\r\n", 403);
                            respBufLen += sprintf(respBuf + respBufLen, "Content-Length: %d\r\n\r\n", 0);

                            sendlen = send(sfd, respBuf, strlen(respBuf), 0);
                            //ROS_INFO("send size %d", sendlen);
                            break ;
                        }
                    }
                }
            }
            else
            {
                break ;
            }
        }
        else
        {
            //ROS_INFO("timeout...");
        }
    }

    pthread_exit(NULL);
}


void *ACCEPT_SERVICE(void *arg)
{
    // 使用预定义的结构体类型
    AcceptThreadData *data = (AcceptThreadData *)arg;
    ros::Publisher pub = data->pub;

    int sockfd, connfd;
    int addreuse = 1;
    uint32_t sockaddr_size = 0;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    struct linger tcpLinger;

    // 修改为pthread_t类型
    pthread_t tid[10];
    int ret, i = 0;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&addreuse, sizeof(int)) == -1)
    {
        pthread_exit(NULL);
    }
    sockaddr_size = sizeof(struct sockaddr_in);
    bzero((char *)&server_addr, sockaddr_size);

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8888);
    inet_pton(AF_INET, LOCAL_IP, &server_addr.sin_addr);  // 使用宏定义的本机IP

    bind(sockfd, (struct sockaddr*)&server_addr, sockaddr_size);
    listen(sockfd, 10);

    while(ros::ok())
    {
        //ROS_INFO("***************************");
        // accept a connection from a socket
        connfd = accept(sockfd, (struct sockaddr*)&client_addr, &sockaddr_size);
        //ROS_INFO("connfd = %d", connfd);
        if (connfd < 0)
        {
            continue;
        }

        /* accept到后去接收解析设备端发送过来的http请求并给予回应  */
#if 1
        // 使用预定义的结构体类型
        struct ThreadData {
            int sfd;
            ros::Publisher pub;
        } *thread_data = (struct ThreadData *)malloc(sizeof(struct ThreadData));
        
        thread_data->sfd = connfd;
        thread_data->pub = pub;

        ret = pthread_create(&tid[i], NULL, HTTP_SERVICE, (void *)thread_data);
        if(ret == -1)
        {
            perror("pthread_create error");
            free(thread_data);
            break;
        }
#endif
        i++;
    }

    pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
    ros::init(argc, argv, NODE_CAMERA);
    ros::NodeHandle nh;

    ros::Publisher pub = nh.advertise<rads::rads_camera>("pradscamera", 10);

    char recvbuff[2048] = {0};
    int sfd;
    int cmd;
    char *pbuf = NULL;
    int len = 0;
    
    // 修改为pthread_t类型
    pthread_t tid;
    int ret;

    sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }

    struct sockaddr_in saddr;
    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(TCP_PORT);
    inet_pton(AF_INET, TCP_IPV4, &saddr.sin_addr);
    
    // 修复：移除重复声明，直接使用已声明的ret变量
    ret = connect(sfd, (struct sockaddr *)&saddr, sizeof(saddr));
    if(ret == -1)
    {
        perror("connect error");
        return -1;
    }

#if 1
    // 此线程处于accept,等待设备的connect,接收并解析报警信息
    AcceptThreadData *accept_data = (AcceptThreadData *)malloc(sizeof(AcceptThreadData));
    accept_data->pub = pub;

    ret = pthread_create(&tid, NULL, ACCEPT_SERVICE, (void *)accept_data);
    if(ret == -1)
    {
        perror("pthread_create error");
        free(accept_data);
        return -1;
    }
#endif

    http_get_alarm(sfd, saddr, pub);

    close(sfd);
    ros::spin();
    return 0;
}
